package com.study.sbsummary.config.promethues;

import com.study.sbsummary.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.UnknownHostException;


@Slf4j
public class Metrics {
    // singleton & 初始化
    private static Metrics instance;
    private static final String bigTeam = "Ydbot.statsd.serving";
    private static String METRICS_IP;
    private static int MAX_TAG_NUM = 10;

    static {
        try {
            METRICS_IP = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
    public static void init(String group, String component, String env) {
        assert instance != null : "Metrics instance 已存在";
        assert StringUtil.hasNullOrEmpty(group, component, env) : "group component tagEnv 不能为空";
        instance = new Metrics(group, component, env);
        //启动serving metrics
        MBootstrap.startup();
    }
    private Metrics() {
    }

    private Metrics(String group, String component, String tagEnv) {
        initConsumerConfig();
        initProducerConfig(group, component, tagEnv);
        //初始化serving metrics单例
        MConfig.getInstance()
                .cConfig(ConsumerConfig.configer())
                .pConfig(ProducerConfig.configer());
    }
    private void initConsumerConfig() {
        if (StringUtil.noNullOrEmpty(METRICS_IP)) {
            ConsumerConfig.configer().serverAddr(new RemoteServerAddr(METRICS_IP, DEFAULT_PORT));
        } else {
            log.error("监控ip为空，若为线上机器，影响监控");
        }
    }

    private void initProducerConfig(String group, String component, String env) {
        ProducerConfig
                .configer()
                ._bigTeam(bigTeam)
                .group(group)
                .component(component)
                .globalTag(Tag.newTag("env", env));
    }

    private static TagMetrics getRealMetrics(METRICS_TYPE metrics_type, Tag tags) {
        return com.yidian.serving.index.metrics.Metrics.tag(metrics_type.value, tags);
    }

    private static Tag assembleTags(String[] tags) {
        assert tags.length < MAX_TAG_NUM : "超过了最大的tag数 : " + MAX_TAG_NUM;
        Tag tag = null;
        if (tags.length > 0) {
            tag = Tag.newTag(String.valueOf(0), tags[0]);
            for (int i = 1; i < tags.length; i++) {
                tag.add(String.valueOf(i), tags[i]);
            }
        }

        if (tag == null) {
            tag = Tag.newTag(String.valueOf(tags.length), METRICS_IP);
        } else {
            tag.add(String.valueOf(tags.length), METRICS_IP);
        }

        return tag;
    }

    // qps
    public static void qps(String... tags) {
        Tag tag = assembleTags(tags);
        getRealMetrics(METRICS_TYPE.QPS, tag).qps(METRICS_TYPE.QPS.value);
    }

    // latency
    public static void latency(long begin, String... tags) {
        Tag tag = assembleTags(tags);
        getRealMetrics(METRICS_TYPE.LATENCY, tag).latency(METRICS_TYPE.QPS.value, begin);
    }

    enum METRICS_TYPE {
        QPS("qps"),
        LATENCY("latency"),
        ;

        private String value;

        METRICS_TYPE(String value) {
            this.value = value;
        }
    }
}
